
local unit_attribute = require 'types.unit_attribute'
local register = unit_attribute.register
local field = unit_attribute.field
local data = load_excel('基础设定.xlsx','属性定义')

local list1 = {}
local list2 = {}
local is_rate = {}
ac.attr_key1 = {}
ac.attr_key2 = {}
ac.attr_key3 = {}
ac.attribute = {}

ac.attr_key1['生命'] = '生命上限'
ac.attr_key1['攻击'] = '基础攻击'
--新自定义
for _,da in pairs(data) do
    local name = da.name
    local key = da.key or name
    if name then
        da.name = name
        da.key = key
        ac.attr_key1[name] = key
        ac.attr_key2[key] = name
        ac.attr_key3[name] = da.title
        
        table.insert(ac.attribute,da)
        if da.is_race then
            is_rate[key] = true
            table.insert(list2,da)
        else
            table.insert(list1,da)
        end
        register(key)
    end
end

--[属性文本]
function sx_tip(key,num)
    local ex = ''
    if is_rate[key] then
        ex = '%'
    end
    if num<10 and num>-10 and num~=math.ceil(num) then
        return ('%s|cff00ff00%+0.1f%s|r'):format(key,num,ex)
    else
        return ('%s|cff00ff00%+0.0f%s|r'):format(key,num,ex)
    end
end

--[表属性文本]
function atts_tip(self,option)
    local tips = {}
	local owner = self.owner
    local sx1 = {}
    local sx2 = {}
    if not option then
        option = {}
        option['sep'] = '|n'
    end
    local color1 = option['color1'] or '|cffff9900%s|r'
    local color2 = option['color2'] or '|cffff9900%s|r'
    for _,da in ipairs(ac.attribute) do
		local name = da.name
        local title = da.title or name
		local num = tonumber(self[name])
		if num and num~=0 then
            local ex = ''
            local color = color1
            local tips = sx1
	        if da.is_race then
                ex = '%'
                tips = sx2
                color = color2
            end
			if num<10 and num>-10 and num~=math.ceil(num) then
                local tip = ('◆%s%+0.1f%s'):format(title,num,ex)
				tips[#tips + 1] = tip
			else
				local tip = ('◆%s%+0.0f%s'):format(title,num,ex)
				tips[#tips + 1] = tip
			end
        end
    end

    local sep = option['sep']
    for _,tip in ipairs(sx2) do
		sx1[#sx1 + 1] = tip
    end
    local tip = table.concat(sx1,sep)
    return tip
end


--[数组属性文本]
function atts_tip2(self,option)
    local data = {}
    for _,da in ipairs(self) do
        local key = da[1]
        local num = da[2]
        if num and num~=0 then
            data[key] = num
        end
    end
    return atts_tip(data,str,option)
end


sc.color_icon = {
    ['攻击速度'] = '|cff00ff00\u{2474}|r',
    ['冷却速度'] = '|cffff00ff\u{2475}|r',
    ['回血加成'] = '|cffccffcc\u{2468}|r',
    ['物理伤害'] = '|cffff6600\u{2467}|r',
    ['魔法伤害'] = '|cff00ccff\u{2466}|r',
    ['基础护甲'] = '|cffff9900\u{2476}|r',
    ['普攻输出'] = '|cffffff00\u{2464}|r',
    ['技能输出'] = '|cffcc99ff\u{2469}|r',
    ['伤害减免'] = '|cffffcc99\u{2478}|r',
    ['物理易伤'] = '|cff00ff00\u{2477}|r',
    ['魔法易伤'] = '|cffff00ff\u{2479}|r',
    ['普攻强化'] = '|cffff6600\u{247F}|r',
    ['普攻强化'] = '|cff00ccff\u{2480}|r',
    ['被动触发几率'] = '|cffffff00\u{2460}|r',
    ['主动触发伤害'] = '|cffcc99ff\u{2460}|r',
}


local types ={
	{1000000000000,'兆'},
	{100000000,'亿'},
	{10000,'万'},
}

--带单位的数字文本
function format_number1(num)
	local num = tonumber(num)
	for i=1,#types do
		local max = types[i][1]
		local ty = types[i][2]
		if num>=max then
			num = num/max
			if num>100 then
				return string.format('%.0f%s',num,ty)
			else
				return string.format('%.1f%s',num,ty)
			end
		end
	end
	return math.ceil(num)
end

function format_number3(num)
	local num = tonumber(num)
	for i=1,#types do
		local max = types[i][1]
		local ty = types[i][2]
		if num>=max then
			num = num/max
			if num>max*10 then
				return string.format('%.0f%s',num,ty)
			else
				return string.format('%.1f%s',num,ty)
			end
		end
	end
	return math.ceil(num)
end

function format_number2(num)
	local str = ('%0.f'):format(tonumber(num))
    local len = str:len()
    local num = math.floor((len-1)/3)
    for i=1,num do
        local a = len - 3*i
        str = ('%s,%s'):format(str:sub(1,a),str:sub(a+1,-1))
    end
    return str
end

local function split_int(data,pattern)
    local strs = split_string(tostring(data),pattern)
    for i,s in ipairs(strs) do
        strs[i] = tonumber(s)
    end
    return strs
end

local function table_mul(data,rate)
    local new = {}
    if type(data)=='number' then
        return data * rate
    end

    for i,num in ipairs(data) do
        new[i] = data[i] * rate
    end
    return new
end



local fmt = ('(.*)([+-][%d]+[%d%.]?[%d]-)([\0%%]?)\n')
function match_sx(str,hide)
    local str = str:gsub(' ','')
    local str = str .. '\n'
    local k,v,c = str:match(fmt)
    if k and v then
        local k = ac.attr_key1[k] or k
        if field[k]==nil and hide==nil then
            log.error('错误属性注册',k)
        end
        return k,tonumber(v),c
    end
end

--将段落文本转换为属性数组
function text_unpack_attrs(text,hide)
    local strs = text:split('\n')
    local data = {}
    
    for a,s in ipairs(strs) do
        local k,v = match_sx(s,hide)
        if k and v then
            data[#data + 1] = {k,tonumber(v)}
        end
    end
    return data
end

function table_sx(data)
    local list = {}
    for name, value in sortpairs(data) do 
        local key = ac.attr_key1[name] or name
        if field[key] then
            list[#list + 1] = {key,value}
        end
    end
    return list
end


--转化伤害公式为具体数值
local str2value = {}
local func_map = {}
setmetatable(str2value,str2value)

function str2value:__tostring()
    return ("[伤害公式]%s"):format(self.str)
end

function str2value:__call(map)
    if map.type=='unit' then
        map = {owner = map}
    end
    return self.func(map)
end

local mt = {}
str2value.__index = mt

function mt:init()
    self.env = setmetatable({}, {
        __index = function (info, key)
            local m = _G['rawget'](info, 'map')
            local v = m and m[key]
            if v then
                return v
            end

            local hero = m and m.owner
            local key = ac.attr_key1[key] or key
            if field[key] and hero and hero.type=='unit' then 
                return hero:get(key)
            end 
            return 0
        end,
    })
    
    self.func = load('return ' .. self.str, self.str, nil, self.env)
end


ac.str2value = function(str)
    if func_map[str] then
        return func_map[str]
    end
    local data = setmetatable({},str2value)
    data.str = str
    data:init()
    func_map[str] = data
    return data
end



--截取伤害公式
local fmt = ('(.*)[\\*X]([%d]+[%d%.]?[%d]-)([\0%%]?)\n')
function dmg_sx(str)
    local str = str:gsub(' ','')
    local str = str .. '\n'
    local k,v,c = str:match(fmt)
    if k and v then
        local k = field[k] and k or ac.attr_key1[k] or k
        if field[k]==nil then
            log.error('错误属性注册',k)
        end
        return k,tonumber(v),c
    end
end

function text_unpack_dmg(text)
    local strs = text:split('+')
    local data = {}
    for a,s in ipairs(strs) do
        local k,v,c = dmg_sx(s)
        if k and v then
            data[#data + 1] = {k,tonumber(v),c}
        end
    end
    return data
end
